package com.snifferx.domain;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import javax.persistence.*;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.authentication.encoding.PasswordEncoder;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * The persistent class for the USERS_LWC database table.
 * 
 */
@Entity
@Table(name = "USERS_LWC")
public class UserEntity implements Serializable, Comparable<UserEntity> {
	private static final long serialVersionUID = 1L;

	@Id
	// ID used customer input @GeneratedValue(strategy = GenerationType.AUTO)
	@Column(updatable = false, unique = true, nullable = false, length = 50)
	private String username;

	@Temporal(TemporalType.DATE)
	@Column(nullable = false)
	private Date creationdate;

	@Column(name = "CUST_INTERESTS", length = 4000)
	private String custInterests;

	@Temporal(TemporalType.DATE)
	private Date dob;

	@Column(nullable = false, length = 100)
	private String email;

	@Column(nullable = false, length = 1)
	private String enabled;

	@Column(name = "FIRST_NAME", length = 50)
	private String firstName;

	@Column(length = 1)
	private String gender;

	@Lob
	private byte[] headshot;

	@Column(name = "LAST_NAME", length = 50)
	private String lastName;

	@Column(name = "LOGIN_ATTEMPTS", nullable = false, precision = 1)
	private BigDecimal loginAttempts;

	@Column(nullable = false, length = 50)
	private String password;

	@Column(name = "SECRET_ANSWER", length = 100)
	private String secretAnswer;

	@Column(name = "SECRET_QUESTION", length = 100)
	private String secretQuestion;

	// bi-directional many-to-one association to AuthorityEntity
	@OneToMany(mappedBy = "user", cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true)
	private List<AuthorityEntity> authorities;

	// will added tag to deal with data[] to streamContent
	@Transient
	private StreamedContent image;

	public UserEntity() {
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Date getCreationdate() {
		return this.creationdate;
	}

	public void setCreationdate(Date creationdate) {
		this.creationdate = creationdate;
	}

	public String getCustInterests() {
		return this.custInterests;
	}

	public void setCustInterests(String custInterests) {
		this.custInterests = custInterests;
	}

	public Date getDob() {
		return this.dob;
	}

	public void setDob(Date dob) {
		this.dob = dob;
	}

	public String getEmail() {
		return this.email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getEnabled() {
		return this.enabled;
	}

	public void setEnabled(String enabled) {
		this.enabled = enabled;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getGender() {
		return this.gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public byte[] getHeadshot() {
		return this.headshot;
	}

	public void setHeadshot(byte[] headshot) {
		this.headshot = headshot;
	}

	public String getLastName() {
		return this.lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public BigDecimal getLoginAttempts() {
		return this.loginAttempts;
	}

	public void setLoginAttempts(BigDecimal loginAttempts) {
		this.loginAttempts = loginAttempts;
	}

	public String getPassword() {
		return this.password;
	}

	// MD5 the input password here
	public void setPassword(String password) {
		PasswordEncoder crypto = new Md5PasswordEncoder();
		this.password = crypto.encodePassword(password, null);
		// this.password = password;
	}

	public String getSecretAnswer() {
		return this.secretAnswer;
	}

	public void setSecretAnswer(String secretAnswer) {
		this.secretAnswer = secretAnswer;
	}

	public String getSecretQuestion() {
		return this.secretQuestion;
	}

	public void setSecretQuestion(String secretQuestion) {
		this.secretQuestion = secretQuestion;
	}

	public List<AuthorityEntity> getAuthorities() {
		return this.authorities;
	}

	public void setAuthorities(List<AuthorityEntity> authorities) {
		this.authorities = authorities;
	}

	public AuthorityEntity addAuthorities(AuthorityEntity authorities) {
		getAuthorities().add(authorities);
		authorities.setUser(this);

		return authorities;
	}

	public AuthorityEntity removeAuthorities(AuthorityEntity authorities) {
		getAuthorities().remove(authorities);
		authorities.setUser(null);

		return authorities;
	}

	public StreamedContent getImage() {
		// addded the handle to streamcontent
		if (this.headshot != null) {
			image = new DefaultStreamedContent(new ByteArrayInputStream(this.headshot), "image/png");
		}
		return image;
	}

	/*
	 * @Override public String toString() { return "UserEntity [username=" +
	 * username + ", creationdate=" + creationdate + ", custInterests=" +
	 * custInterests + ", dob=" + dob + ", email=" + email + ", enabled=" +
	 * enabled + ", firstName=" + firstName + ", gender=" + gender +
	 * ", headshot=" + Arrays.toString(headshot) + ", lastName=" + lastName +
	 * ", loginAttempts=" + loginAttempts + ", password=" + password +
	 * ", secretAnswer=" + secretAnswer + ", secretQuestion=" + secretQuestion +
	 * ", authorities=" + authorities + ", image=" + image + "]"; }
	 */

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((username == null) ? 0 : username.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		UserEntity other = (UserEntity) obj;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}

	@Override
	public int compareTo(UserEntity o) {
		// 先按firstName排序
		if (this.getFirstName().compareTo(o.getFirstName()) > 0) {
			return 1;
		}
		if (this.getFirstName().compareTo(o.getFirstName()) < 0) {
			return -1;
		}
		// 按lastName排序
		if (this.getLastName().compareTo(o.getLastName()) > 0) {
			return 1;
		}
		if (this.getLastName().compareTo(o.getLastName()) < 0) {
			return -1;
		}

		return 0;
	}

}